package hust.iamk.lock;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import android.util.Log;

import com.cooliris.media.LocalDataSource;

public class SecurityFileUtils {
	private static final String KEY = "@HUST-SS-IAMK14#";
	public static String FILE_EXTENSION = ".iamk";
	public static void encrypt(String filePath) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
		
		FileInputStream fis = new FileInputStream(filePath);

		// This stream write the encrypted text. This stream will be wrapped by another stream.
		String fileOutputPath = LocalDataSource.LOCK_BUCKET_NAME + getFileName(filePath, 0) + FILE_EXTENSION;
		
		Log.d("encrypt", filePath + " / " +  fileOutputPath);
		FileOutputStream fos = new FileOutputStream(fileOutputPath);
		
		// Length is 16 byte
		SecretKeySpec sks = new SecretKeySpec(KEY.getBytes(),"AES");
		// Create cipher
		Cipher cipher = Cipher.getInstance("AES");
		cipher.init(Cipher.ENCRYPT_MODE, sks);
		// Wrap the output stream
		CipherOutputStream cos = new CipherOutputStream(fos, cipher);
		// Write bytes
		int b;
		byte[] d = new byte[8];
		while ((b = fis.read(d)) != -1) {
			cos.write(d, 0, b);
		}
		// Flush and close streams.
		cos.flush();
		cos.close();
		fis.close();
	}
	
	public static void decrypt(String filePath, String desPath) throws IOException, NoSuchAlgorithmException,	NoSuchPaddingException, InvalidKeyException {
		FileInputStream fis = new FileInputStream(filePath);

		FileOutputStream fos = new FileOutputStream(desPath + "/" + getFileName(filePath, 1) );
		SecretKeySpec sks = new SecretKeySpec(KEY.getBytes(),"AES");
		Cipher cipher = Cipher.getInstance("AES");
		cipher.init(Cipher.DECRYPT_MODE, sks);
		CipherInputStream cis = new CipherInputStream(fis, cipher);
		int b;
		byte[] d = new byte[8];
		while ((b = cis.read(d)) != -1) {
			fos.write(d, 0, b);
		}
		
		
		fos.flush();
		fos.close();
		cis.close();
	}
	
	@SuppressWarnings("resource")
	public static void copyFile(File src, File dst) throws IOException
	{
	    FileChannel inChannel = new FileInputStream(src).getChannel();
	    FileChannel outChannel = new FileOutputStream(dst).getChannel();
	    try
	    {
	        inChannel.transferTo(0, inChannel.size(), outChannel);
	    }catch(Exception e){
	    	e.printStackTrace();
	    }
	    finally
	    {
	        if (inChannel != null)
	            inChannel.close();
	        if (outChannel != null)
	            outChannel.close();
	    }
	}
	
	public static String getFileName(String filePath,int flag){
		String fileName;
		if(flag == 0) 
			// Encrypt
			fileName = filePath.substring(filePath.lastIndexOf("/"), filePath.length());
		else{ 
			// Decrypt
			fileName = filePath.substring(filePath.lastIndexOf("/"), filePath.length());
			fileName = fileName.replace(".iamk", "");
		}
		return fileName;
	}
	
	
	static void copyFile2(File src,File dst) throws IOException{
        if(src.getAbsolutePath().toString().equals(dst.getAbsolutePath().toString())){
            return;
        }else{
            InputStream is=new FileInputStream(src);
            OutputStream os=new FileOutputStream(dst);
            byte[] buff=new byte[1024];
            int len;
            while((len=is.read(buff))>0){
                os.write(buff,0,len);
            }
            is.close();
            os.close();
        }
    }
}
